﻿using ContourSplit.Scaffold;
using Emgu.CV;
using Emgu.CV.Util;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ContourSplit.Forms
{
	public partial class Setting : Form
	{
		private ImageProcessor p;
		private Mat m;
		private bool byVertical;
		public Setting()
		{
			InitializeComponent();
			tbWidthInPX.DataBindings.Add(new Binding("Text", Config.config, "WidthInPX", true));
			tBarThres.DataBindings.Add(new Binding("Value", Config.config, "Threshold", true));
			tbMCPerPX.DataBindings.Add(new Binding("Text", Config.config, "MCPerPX",true));
			tbMCPerDG.DataBindings.Add(new Binding("Text", Config.config,"MCPerDG",true));
			tbZInitH.DataBindings.Add(new Binding("Text", Config.config, "ZInitH", true));
			tbZActH.DataBindings.Add(new Binding("Text", Config.config, "ZActH", true));
			tbMCPerMM.DataBindings.Add(new Binding("Text", Config.config, "MCPerMM", true));
			tbVMax.DataBindings.Add(new Binding("Text", Config.config, "VMax", true));
			tbVMin.DataBindings.Add(new Binding("Text", Config.config, "VMin", true));
			tbTacc.DataBindings.Add(new Binding("Text", Config.config, "Tacc", true));

			var x = new Binding("Text", Config.config, "Offset", true);
			x.Parse += (sender, e) => {e.Value = new PointConverter().ConvertFromString(e.Value.ToString());};
			x.Format += (sender, e) => {e.Value = new PointConverter().ConvertToString(e.Value);};
			tbOffset.DataBindings.Add(x);

			tbPasses.DataBindings.Add(new Binding("Text",Config.config,"Passes",true));
			cbPaintOnFinally.DataBindings.Add(new Binding("Checked", Config.config, "PaintOnFinally", true));
			tbGluePort.DataBindings.Add(new Binding("Text", Config.config, "GluePort",true));
			tbCompletePort.DataBindings.Add(new Binding("Text", Config.config, "CompletePort", true));

			tbChessHei.DataBindings.Add(new Binding("Text", Config.config, "ChessHei", true));
			tbChessWid.DataBindings.Add(new Binding("Text", Config.config, "ChessWid", true));

			m = CvInvoke.Imread(@"sample.JPG");
			byVertical = true;

			tBarThres.Enabled = false;
			imageBox1.Enabled = false;
		}

		private void btnOK_Click(object sender, EventArgs e)
		{
			if (Config.config.Save())
			{
				DialogResult = DialogResult.OK;
				Close();
			}
			else
			{
				MessageBox.Show("保存文件失败");
			}
		}

		private void tBarThres_ValueChanged(object sender, EventArgs e)
		{
			if (sender is Emgu.CV.UI.ImageBox)
				byVertical = !byVertical;
			Console.WriteLine($"threshold: {tBarThres.Value}");
			p = new ImageProcessor() {
				Threshold = tBarThres.Value,
				WidthInPX = Config.config.WidthInPX,
			};
			Mat undist = new Mat();
			Config.config.calibrator.Undistort(m, undist);
			p.ExtractMaxContour(undist, out VectorOfPoint maxContour);
			Mat result = p.SplitContour(undist, maxContour, out List<Rectangle> rects, byVertical, true);
			Console.WriteLine($"找到{rects.Count}个:");
			foreach (var item in rects)
			{
				if (byVertical)
					Console.WriteLine($"X: {item.X}; Y: [{item.Y},{item.Bottom}]");
				else
					Console.WriteLine($"X: [{item.X},{item.Right}]; Y: {item.Y}");
			}
			Console.WriteLine("-----------------");
			imageBox1.Image = result;
		}

		private void btnCalibrateCam_Click(object sender, EventArgs e)
		{
			Config.config.calibrator = new Calibrator(Config.config.ChessWid, Config.config.ChessHei, "VID5.xml");
			if (!Config.config.calibrator.Calibrate("camera.yml"))
			{
				Console.WriteLine("校准失败");
				tBarThres.Enabled = false;
				imageBox1.Enabled = false;
				tBarThres.ValueChanged -= tBarThres_ValueChanged;
				imageBox1.Click -= tBarThres_ValueChanged;
			}
			else
			{
				Console.WriteLine("校准成功");
				tBarThres.Enabled = true;
				imageBox1.Enabled = true;
				tBarThres.ValueChanged += tBarThres_ValueChanged;
				imageBox1.Click += tBarThres_ValueChanged;
				(sender as Button).Enabled = false;
				tBarThres_ValueChanged(tBarThres, new EventArgs());
			}
		}
	}
}
